package com.smartum.mpr.client.view;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.data.RecordList;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.Img;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.tile.TileGrid;
import com.smartgwt.client.widgets.tile.events.RecordClickEvent;
import com.smartgwt.client.widgets.tile.events.RecordClickHandler;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;
import com.smartgwt.client.widgets.viewer.DetailViewerField;
import com.smartum.mpr.client.services.ImageService;
import com.smartum.mpr.client.services.ImageServiceAsync;

import java.util.HashMap;
import java.util.Map;

/**
 */
public class ImageViewerView extends VLayout {

    private static final String DECLINE_ICON = "decline.png";
    private static final String ACCEPT_ICON = "accept.png";
    private static final String DECLINE_DIS_ICON = "decline_dis.png";
    private static final String ACCEPT_DIS_ICON = "accept_dis.png";
    final Map<Long, Record> declineCollection = new HashMap<Long, Record>();
    final Map<Long, Record> acceptCollection = new HashMap<Long, Record>();

    public ImageViewerView() {
        GWT.log("[CONSTRUCT COMPONENT] image viewer");

        final TileGrid tileGrid = new TileGrid() {

            @Override
            public Canvas getTile(final Record record) {

                final Canvas canvas = super.getTile(record);
                final ImgButton removeButton = getRemoveButton(canvas);
                final ImgButton acceptButton = getAcceptButton(canvas);

                if (canvas.getChildren().length == 0) {
                    canvas.addChild(removeButton);
                }
                if (canvas.getChildren().length == 1) {
                    canvas.addChild(acceptButton);
                }

                return canvas;
            }

            @Override
            public Canvas getTile(int recordNum) {

                return this.getTile((ImageRecord) this.getRecordList().get(recordNum));
            }


            private ImgButton getAcceptButton(final Canvas canvas) {
                final ImgButton acceptButton = new ImgButton();
                acceptButton.setSrc(ACCEPT_DIS_ICON);
                acceptButton.setShowHover(true);
                acceptButton.setWidth(24);
                acceptButton.setHeight(24);
                acceptButton.setShowFocused(false);
                acceptButton.setShowRollOver(false);
                acceptButton.setPrompt("Approve image");
                acceptButton.setSnapTo("BL");
                acceptButton.setMargin(2);

                acceptButton.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {
                        if (ACCEPT_ICON.equals(acceptButton.getSrc())) {
                            ((ImgButton) canvas.getChildren()[1]).setSrc(ACCEPT_DIS_ICON);
                        } else {
                            acceptButton.setSrc(ACCEPT_ICON);
                        }
                        ((ImgButton) canvas.getChildren()[0]).setSrc(DECLINE_DIS_ICON);
                    }
                });
                return acceptButton;
            }

            private ImgButton getRemoveButton(final Canvas canvas) {
                final ImgButton removeButton = new ImgButton();
                removeButton.setSrc(DECLINE_DIS_ICON);
                removeButton.setShowHover(true);
                removeButton.setPrompt("Disapprove image");
                removeButton.setWidth(24);
                removeButton.setHeight(24);
                removeButton.setShowFocused(false);
                removeButton.setShowRollOver(false);
                removeButton.setSnapTo("BR");
                removeButton.setShowDown(false);
                removeButton.setMargin(2);

                removeButton.addClickHandler(new ClickHandler() {
                    public void onClick(ClickEvent event) {

                        if (DECLINE_ICON.equals(removeButton.getSrc())) {
                            ((ImgButton) canvas.getChildren()[0]).setSrc(DECLINE_DIS_ICON);
                        } else {
                            removeButton.setSrc(DECLINE_ICON);
                        }
                        ((ImgButton) canvas.getChildren()[1]).setSrc(ACCEPT_DIS_ICON);
                    }
                });
                return removeButton;
            }

        };
        tileGrid.setTileWidth(200);
        tileGrid.setTileHeight(200);
        tileGrid.setHeight100();
        tileGrid.setWidth100();
        tileGrid.setCanReorderTiles(true);
        tileGrid.setShowAllRecords(true);
        tileGrid.setCanFocus(false);

        tileGrid.addRecordClickHandler(new RecordClickHandler() {
            @Override
            public void onRecordClick(RecordClickEvent event) {
                final ImageRecord record = (ImageRecord) event.getRecord();
                final Canvas tile = tileGrid.getTile(record);
                final Canvas[] children = tile.getChildren();

                boolean applyedByX = (children[0].getAbsoluteLeft() < event.getX() && (children[0].getAbsoluteLeft() + children[0].getWidth()) > event.getX()) ||
                        (children[1].getAbsoluteLeft() < event.getX() && (children[1].getAbsoluteLeft() + children[1].getWidth()) > event.getX()) ? false : true;
                boolean applyedByY = (children[0].getAbsoluteTop() < event.getX() && (children[0].getAbsoluteTop() + children[0].getHeight()) > event.getX()) ||
                        (children[1].getAbsoluteTop() < event.getX() && (children[1].getAbsoluteTop() + children[1].getHeight()) > event.getX()) ? false : true;
                if (!applyedByX || !applyedByY) {
                    return;
                }

                showPopupWithRealImage(record);
            }
        });


        DetailViewerField pictureField = new DetailViewerField("littlePicture");
        pictureField.setType("image");
        pictureField.setImageWidth(186);
        pictureField.setImageHeight(186);

        tileGrid.setFields(pictureField);

        ToolStripButton acceptAll = new ToolStripButton("Accept All");
        acceptAll.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                collectImages(tileGrid, DECLINE_DIS_ICON, ACCEPT_ICON);
            }
        });
        ToolStripButton declineAll = new ToolStripButton("Decline All");
        declineAll.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                collectImages(tileGrid, DECLINE_ICON, ACCEPT_DIS_ICON);
            }
        });

        ToolStripButton submitButton = new ToolStripButton("Submit");

        final GridPager gridPager = new GridPager(tileGrid, 10, acceptAll, declineAll, submitButton);
        submitButton.addClickHandler(new ClickHandler() {
            public void onClick(ClickEvent event) {
                final ImageServiceAsync imageServiceAsync = GWT.create(ImageService.class);

                submitForm(tileGrid);
                final Long[] acceptIds = acceptCollection.keySet().toArray(new Long[0]);
                final Long[] declineIds = declineCollection.keySet().toArray(new Long[0]);

                imageServiceAsync.submitImages(gridPager.getPageSize(), acceptIds, declineIds, new AsyncCallback<Void>() {
                    public void onFailure(Throwable caught) {
                        GWT.log("esception");
                    }

                    public void onSuccess(Void result) {
                        gridPager.getNewRecords(tileGrid, -1, 1);
                        collectImages(tileGrid, DECLINE_DIS_ICON, ACCEPT_DIS_ICON);
                        declineCollection.clear();
                        acceptCollection.clear();
                    }
                });
            }
        });

        setWidth100();
        setHeight100();
        addMember(tileGrid);
        addMember(gridPager);
    }

    private void showPopupWithRealImage(ImageRecord record) {
        final String originalPicture = record.getPicture();
        final Img originalImg = new Img(originalPicture);
        originalImg.setHeight(640);
        originalImg.setWidth(640);

        final Window winModal = new Window();
        winModal.setModalMaskOpacity(80);
        winModal.setIsModal(true);
        winModal.addItem(originalImg);
        winModal.setShowModalMask(true);
        winModal.setLayoutMargin(0);
        winModal.setWidth(652);
        winModal.setHeight(670);
        winModal.setTitle(record.getName());
        winModal.setShowMinimizeButton(false);
        winModal.centerInPage();
        winModal.setCanFocus(true);
        winModal.show();
        winModal.focus();
    }

    private void collectImages(TileGrid tileGrid, String declineButtonStyle, String acceptButtonStyle) {
        declineCollection.clear();
        acceptCollection.clear();

        final RecordList recordList = tileGrid.getRecordList();
        for (int i = 0; i < recordList.getLength(); i++) {

            final Canvas tile = tileGrid.getTile(i);

            final Canvas[] children = tile.getChildren();
            if (children.length == 2) {
                ((ImgButton) children[0]).setSrc(declineButtonStyle);
                ((ImgButton) children[1]).setSrc(acceptButtonStyle);
            }
        }
    }

    private void submitForm(TileGrid tileGrid) {
        final RecordList recordList = tileGrid.getRecordList();
        for (int i = 0; i < recordList.getLength(); i++) {

            final ImageRecord record = (ImageRecord) recordList.get(i);
            final Canvas tile = tileGrid.getTile(i);

            final Canvas[] children = tile.getChildren();
            String declineButtonSrc = ((ImgButton) children[0]).getSrc();
            String acceptButtonSrc = ((ImgButton) children[1]).getSrc();

            if (DECLINE_DIS_ICON.equals(declineButtonSrc) && ACCEPT_ICON.equals(acceptButtonSrc)) {
                acceptCollection.put(record.getId(), record);
            } else if (DECLINE_ICON.equals(declineButtonSrc) && ACCEPT_DIS_ICON.equals(acceptButtonSrc)) {
                declineCollection.put(record.getId(), record);
            }
        }
    }
}
